package org.facyt.vacas.services.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.facyt.commons.util.StringUtils;
import org.facyt.vacas.daos.ClasificacionDAO;
import org.facyt.vacas.daos.ComponenteValorDAO;
import org.facyt.vacas.daos.GrupoDAO;
import org.facyt.vacas.daos.MateriaPrimaDAO;
import org.facyt.vacas.daos.UnidadDAO;
import org.facyt.vacas.entities.login.Grupo;
import org.facyt.vacas.entities.vacas.Clasificacion;
import org.facyt.vacas.entities.vacas.Componente;
import org.facyt.vacas.entities.vacas.ComponenteValor;
import org.facyt.vacas.entities.vacas.MateriaPrima;
import org.facyt.vacas.entities.vacas.Unidad;
import org.facyt.vacas.services.MateriasPrimasService;
import org.facyt.vacas.services.utils.OrdenarMateriaPrimaNombre;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MateriasPrimasServiceImpl implements MateriasPrimasService {
	private static final Log logger = LogFactory
			.getLog(MateriasPrimasServiceImpl.class);

	@Autowired
	private MateriaPrimaDAO materiaPrimaDao;
	
	@Autowired
	private UnidadDAO unidadDAO;
	
	@Autowired
	private ClasificacionDAO clasificacionDAO;
	
	@Autowired
	private ComponenteValorDAO componenteValorDao;
	
	@Autowired
	private GrupoDAO grupoDAO;
//	private String mensaje = "";

	public MateriaPrima getMateriaPrimaById(Integer idMp) throws Exception {
		return materiaPrimaDao.getMateriaPrimaById(idMp);

	}

	public List<MateriaPrima> getTodasMateriasPrima(long idGrupoUsuario)
			throws Exception {
		logger.info("Se obtienen todas las materias primas");
		List<MateriaPrima> lista = materiaPrimaDao
				.getAllMateriaPrima(idGrupoUsuario);

		Collections.sort(lista, new OrdenarMateriaPrimaNombre());

		return lista;
	}

	@Transactional
	public MateriaPrima nuevaMp(long idGrupoUsuario, String descripcion,
			long idUnidad, BigDecimal costo, long idClasificacion)
			throws Exception {

		Unidad unidad = this.unidadDAO.getUnidadById(Long.valueOf(idUnidad)
				.intValue());

		Clasificacion clasificacion = this.clasificacionDAO
				.getClasificacionById(Long.valueOf(idClasificacion).intValue());

		Grupo grupo = this.grupoDAO.getGrupoById(Long.valueOf(idGrupoUsuario)
				.intValue());

		MateriaPrima mp = materiaPrimaDao.nuevaMateriaPrima(grupo, descripcion,
				unidad, costo, clasificacion);

		mp = materiaPrimaDao.getMateriaPrimaById(mp.getId());
		return mp;
	}

	@Transactional
	public MateriaPrima updateMp(long idMP, long idUnidad, BigDecimal costo,
			long idClasificacion, String nombre) throws Exception {

		Unidad unidad = this.unidadDAO.getUnidadById(Long.valueOf(idUnidad)
				.intValue());

		Clasificacion clasificacion = this.clasificacionDAO
				.getClasificacionById(Long.valueOf(idClasificacion).intValue());

		MateriaPrima mp = materiaPrimaDao.updateMateriaPrima(idMP, unidad,
				costo, clasificacion, nombre);

		mp = materiaPrimaDao.getMateriaPrimaById(mp.getId());
		return mp;
	}

	@Transactional
	public MateriaPrima updateMp(long idMP, long idUnidad, BigDecimal costo,
			long idClasificacion) throws Exception {

		Unidad unidad = this.unidadDAO.getUnidadById(Long.valueOf(idUnidad)
				.intValue());

		Clasificacion clasificacion = this.clasificacionDAO
				.getClasificacionById(Long.valueOf(idClasificacion).intValue());

		MateriaPrima mp = materiaPrimaDao.updateMateriaPrima(idMP, unidad,
				costo, clasificacion);

		mp = materiaPrimaDao.getMateriaPrimaById(mp.getId());
		return mp;
	}

	public ComponenteValor getComponenteFromComposicion(MateriaPrima mp,
			Componente componente) {
		ComponenteValor cv = null;

		// ComponenteValor resultado =
		// materiaPrimaDao.getComponenteFromComposicion(mp, componente);

		boolean noEncontrado = false;
		List<ComponenteValor> listadoCV = mp.getComposicion();
		for (int j = 0; j < listadoCV.size() && !noEncontrado; j++) {
			cv = (ComponenteValor) listadoCV.get(j);
			if ((cv).getComponente().equals(componente)) {
				noEncontrado = true;
				return cv;
			}
		}

		// if(resultado != null)
		// return resultado;
		// else{
		// si la mp no aporta cantiadad de este componente, es decir que no esta
		// en su composicion
		// se devuelve un componente de cantidad 0.
		ComponenteValor cv1 = new ComponenteValor();
		cv1.setComponente(componente);
		cv1.setCantidad(BigDecimal.ZERO);
		return cv1;
		// }

	}

	/**
	 * @return
	 */

	public int getCalculoColumnas(ArrayList<MateriaPrima> lista) {

		int cant = 0;
		Iterator mps = lista.iterator();
		int cantmp = 0;
		int cantComp = 0;
		while (mps.hasNext()) {
			MateriaPrima m = (MateriaPrima) mps.next();
			cantmp++;
			cantComp += m.getComposicion().size();
		}

		return cantComp;
	}

	public String getCostoXUnidadString(MateriaPrima materiaPrima) {
		Unidad unidadId = materiaPrima.getUnidad();
		if (unidadId != null
				&& materiaPrima.getCosto().compareTo(BigDecimal.ZERO) >= 0) {
			return StringUtils.getSimela2decimales(materiaPrima.getCosto()
					.toString()) + " " +
			// GestorPresentacion.getInstance().getValor("frame.gestionrestricciones.pesos")+
					"$/" + unidadId.getDescripcion();
		} else
			return "";
	}

	// public byte[] imprimirMp(UsuarioDTO usuario, String mpaimprimir,
	// HashMap hash, URI urlJasper) throws Exception {
	// try {
	//
	// long idMp = Long.valueOf((String) mpaimprimir);
	// MateriaPrima mp = null;
	// try {
	// mp = materiaPrimaDao.getMateriaPrimaById(idMp);
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// logger.error("",e);
	// }
	//
	// return Reportes.reporteMP(mp, usuario, hash, urlJasper);
	//
	// } catch (ExceptionAplicacion e) {
	// logger.error("",e);
	//
	// mensaje = "No se puedo imprimir la planilla de formula. ";
	// throw new ExceptionAplicacion(mensaje,
	// ConstantesDTO.TipoException.INFORMACION);
	//
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// logger.error("",e);
	// }
	// return null;
	// }
	//
	//
	// public byte[] imprimirLitadoMp(UsuarioDTO usuario, HashMap hash,
	// URI urlJasper) throws Exception {
	// try {
	//
	// return Reportes.reporteListaMP(usuario, hash, urlJasper);
	//
	// } catch (ExceptionAplicacion e) {
	// logger.error("",e);
	//
	// mensaje = "No se puedo imprimir la planilla de formula. ";
	// throw new ExceptionAplicacion(mensaje,
	// ConstantesDTO.TipoException.INFORMACION);
	//
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// logger.error("",e);
	// }
	// return null;
	// }
	//
	//
	// public byte[] imprimirLitadoMpCompleto(UsuarioDTO usuario, HashMap hash,
	// URI urlJasper) throws Exception {
	// try {
	//
	// return Reportes.reporte_todas_MP(usuario, hash, urlJasper);
	//
	// } catch (ExceptionAplicacion e) {
	// logger.error("",e);
	//
	// mensaje = "No se puedo imprimir la planilla de formula. ";
	// throw new ExceptionAplicacion(mensaje,
	// ConstantesDTO.TipoException.INFORMACION);
	//
	// } catch (Exception e) {
	// // TODO Auto-generated catch block
	// logger.error("",e);
	// }
	// return null;
	// }

	@Transactional
	public ComponenteValor updateCV(Integer idComponente, BigDecimal cantidad,
			MateriaPrima mp) throws Exception {
		ComponenteValor cv = materiaPrimaDao.getComponenteFromComposicion(mp,
				idComponente);
		return componenteValorDao.updateCV(cv, cantidad, mp, idComponente);
	}

	public MateriaPrima getMateriaPrimaByNombre(String nombre) throws Exception {
		return materiaPrimaDao.getMateriaPrimaByNombre(nombre);

	}

	public MateriaPrima getMpByNombreYGrupo(String nombre, long grupo)
			throws Exception {
		return materiaPrimaDao.getMateriaPrimaByNombreYGrupo(nombre, grupo);
	}

	public String toStringCodDescrip(MateriaPrima materiaPrima) {
		return materiaPrima.getId() + " - " + materiaPrima.getDescripcion();
	}

	public Object getCostoXUnidadString(MateriaPrima mp,
			BigDecimal costoMPaportada) {
		// TODO Auto-generated method stub
		return null;
	}

}